package com.berchen.方法引用与构造器引用;

import com.berchen.Lambda表达式.Employee;
import org.junit.Test;

import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 方法引用：若Lambda体中的内容有方法已经实现了，那么我们可以使用方法引用。
 * 方法引用可以理解为是Lambda表达式的另外一种表现形式。
 * 【当Lambda体中的内容已经有方法A实现】了，并且A方法与该函数式接口中的方法的【参数列表与返回值】一致。那么就可以使用方法引用代替Lambda。
 * <p>
 * <p>
 * 主要有三种语法格式：
 * 1、对象::实例方法名。
 * 2、类::静态方法名。
 * 3、类::实例方法名。
 * 如果Lambda的第一个参数是Lambda体中的方法的调用者，Lambda的第二个参数是Lambda体中方法的参数。那么我们就可以使用类::实例方法名格式。
 */
public class TestMethod {

    @Test
    public void test1() {

        // 1、对象::实例方法名。
        Consumer<String> con = s -> System.out.println(s);
        con.accept("berchen");

        // Lambda 体重的内容已经有方法实现了，只要满足了该方法的参数列表与返回值与函数是接口中的方法的参数列表与返回值一致。就直接可以引用该方法。
        Consumer<String> cons = System.out::println;
        cons.accept("chen");

        Employee emp = new Employee();
        Supplier<String> sup = () -> emp.getName();

        // 方法引用，那么Supplier类中get方法的返回值与Employee中的getName方法的返回值相同。才可以。
        Supplier<String> sup1 = emp::getName;
        sup1.get();
    }

    @Test
    public void test2() {

        // 2、类::静态方法名。
        Comparator<Integer> com = (x, y) -> Integer.compare(x, y);    // 现成的Integer.compare(x.y)方法，直接使用方法引用调用。
        Comparator<Integer> com1 = Integer::compareTo;
        com1.compare(1, 2);
    }

    @Test
    public void test3() {

        // 3、类::实例方法名。
        BiPredicate<String, String> bipre = (s1, s2) -> s1.equals(s2);

        // 如果 Lambda体中的方法的调用者是Lambda的第一个参数，体中的方法的参数是Lambda的第二个参数。我们就可以使用类::实例方法格式。
        BiPredicate<String, String> bipre1 = String::equals;
        boolean test = bipre1.test("chen", "wan");
        System.out.println(test);

    }
}
